package com.megvii.koala.log;

import com.megvii.corelib.util.DateTimeUtil;

import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

/**
 * Created by linyue on 16/1/12.
 */
public class MegviiLogger
{
    public static final int DEFAULT_CACHE_SIZE = 1000;

    private static MegviiLogger instance = new MegviiLogger();

    private boolean isReleaseVersion = false;

    private int cacheSize = DEFAULT_CACHE_SIZE;

    private LinkedList<MegviiLogData> queueD;

    public MegviiLogger()
    {
        this(DEFAULT_CACHE_SIZE);
    }

    public MegviiLogger(int cacheSize)
    {
        super();
        this.cacheSize = cacheSize;
        this.queueD = new LinkedList<>();
    }

    public static MegviiLogger getDefaultLogger()
    {
        return instance;
    }

    public void setReleaseMode(boolean isReleaseMode)
    {
        this.isReleaseVersion = isReleaseMode;
    }

    public void logD(String tag, String message)
    {
        if (!isReleaseVersion)
        {
            synchronized (queueD)
            {
                if (queueD.size() >= cacheSize)
                {
                    queueD.removeFirst();
                }
                queueD.addLast(new MegviiLogData(System.currentTimeMillis(), tag, message));
            }
        }
    }

    public void flushD(OutputStream os, int amount, boolean containsDateTime)
    {
        OutputStreamWriter osw = new OutputStreamWriter(os);
        PrintWriter pw = new PrintWriter(osw);
        synchronized (queueD)
        {
            Iterator<MegviiLogData> iterator = queueD.iterator();
            while (iterator.hasNext() && amount > 0)
            {
                MegviiLogData logData = iterator.next();
                if (containsDateTime)
                {
                    String dateTime = DateTimeUtil.getFormattedDateTime(logData.timestamp, true);
                    pw.append("[");
                    pw.append(dateTime);
                    pw.append("] ");
                    pw.append("[");
                    pw.append(logData.tag);
                    pw.append("] ");
                    pw.println(logData.message);
                }
                amount--;
            }
            pw.flush();
        }
    }

    public void flushAllD(OutputStream os, boolean containsDateTime)
    {
        flushD(os, Integer.MAX_VALUE, containsDateTime);
    }

    public List<String> getListD(boolean containsDateTime)
    {
        ArrayList<String> result = new ArrayList<>();
        synchronized (queueD)
        {
            Iterator<MegviiLogData> iterator = queueD.iterator();
            while (iterator.hasNext())
            {
                StringBuffer buffer = new StringBuffer();
                MegviiLogData logData = iterator.next();
                if (containsDateTime)
                {
                    String dateTime = DateTimeUtil.getFormattedDateTime(logData.timestamp, true);
                    buffer.append("[");
                    buffer.append(dateTime);
                    buffer.append("] ");
                    buffer.append("[");
                    buffer.append(logData.tag);
                    buffer.append("] ");
                    buffer.append(logData.message);
                }
                String line = buffer.toString();
                result.add(line);
            }
        }
        return result;
    }
}
